package me.baicai.modules.belldandy.gcb.service.impl;

import com.alibaba.fastjson.JSONObject;
import me.baicai.modules.belldandy.gcb.domain.CrmOrder;
import me.baicai.modules.belldandy.gcb.domain.Project;
import me.baicai.modules.belldandy.gcb.repository.ProjectRepository;
import me.baicai.utils.FileUtil;
import me.baicai.utils.PageUtil;
import me.baicai.utils.QueryHelp;
import me.baicai.modules.belldandy.gcb.repository.CrmOrderRepository;
import me.baicai.modules.belldandy.gcb.service.CrmOrderService;
import me.baicai.modules.belldandy.gcb.service.dto.CrmOrderDTO;
import me.baicai.modules.belldandy.gcb.service.dto.CrmOrderQueryCriteria;
import me.baicai.modules.belldandy.gcb.service.mapper.CrmOrderMapper;
import me.baicai.utils.ValidationUtil;
import me.baicai.weixin.entity.gcb.Finance;
import me.baicai.weixin.identity.repository.FinanceRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.IdUtil;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;


/**
* @author 超级大白菜
* @date 2020-04-17
*/
@Service
@CacheConfig(cacheNames = "crmOrder")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class CrmOrderServiceImpl implements CrmOrderService {

    private final CrmOrderRepository crmOrderRepository;

    private final CrmOrderMapper crmOrderMapper;

    private final ProjectRepository projectRepository;

    private final FinanceRepository financeRepository;

    public CrmOrderServiceImpl(CrmOrderRepository crmOrderRepository,
                               CrmOrderMapper crmOrderMapper,
                               ProjectRepository projectRepository,
                               FinanceRepository financeRepository) {
        this.crmOrderRepository = crmOrderRepository;
        this.crmOrderMapper = crmOrderMapper;
        this.projectRepository = projectRepository;
        this.financeRepository = financeRepository;
    }

    @Override
    @Cacheable
    public Map<String,Object> queryAll(CrmOrderQueryCriteria criteria, Pageable pageable){
        Page<CrmOrder> page = crmOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(crmOrderMapper::toDto));
    }

    @Override
    @Cacheable
    public List<CrmOrderDTO> queryAll(CrmOrderQueryCriteria criteria){
        return crmOrderMapper.toDto(crmOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Cacheable(key = "#p0")
    public CrmOrderDTO findById(String id) {
        CrmOrder crmOrder = crmOrderRepository.findById(id).orElseGet(CrmOrder::new);
        ValidationUtil.isNull(crmOrder.getId(),"CrmOrder","id",id);
        return crmOrderMapper.toDto(crmOrder);
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public CrmOrderDTO create(CrmOrder resources) {
        resources.setId(IdUtil.simpleUUID());
        Finance finance = new Finance();
        finance.setType("in");
        finance.setAmount(resources.getProfitamount().toString());
        finance.setSouce("外贸");
        Project project = projectRepository.findProjectById(resources.getProjectid());
        finance.setRemark(project.getDescription());
        finance.setCreateDate(new Date());
        finance.setCreated(resources.getId());
        financeRepository.save(finance);
        Project project1 = projectRepository.findProjectById(resources.getProjectid());
        project1.setAmount(project.getAmount()+resources.getOrderamount());
        project1.setIncome(project.getIncome()+resources.getProfitamount());
        projectRepository.save(project);
        return crmOrderMapper.toDto(crmOrderRepository.save(resources));
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(CrmOrder resources) {
        CrmOrder crmOrder = crmOrderRepository.findById(resources.getId()).orElseGet(CrmOrder::new);
        ValidationUtil.isNull( crmOrder.getId(),"CrmOrder","id",resources.getId());
        crmOrder.copy(resources);
        crmOrderRepository.save(crmOrder);

        financeRepository.deleteAllByCreated(crmOrder.getId());
        Finance finance = new Finance();
        finance.setType("in");
        finance.setAmount(crmOrder.getProfitamount().toString());
        finance.setSouce("外贸");
        Project project = projectRepository.findProjectById(crmOrder.getProjectid());
        finance.setRemark(project.getDescription());
        finance.setCreateDate(new Date());
        finance.setCreated(crmOrder.getId());
        financeRepository.save(finance);

        Project project1 = projectRepository.findProjectById(resources.getProjectid());
        JSONObject jsonObject = projectRepository.getData(resources.getProjectid());
        project1.setAmount(jsonObject.getFloat("orderamount"));
        project1.setIncome(jsonObject.getFloat("profitamount"));
        projectRepository.save(project);
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        CrmOrder crmOrder = crmOrderRepository.getOne(id);
        Project project1 = projectRepository.findProjectById(crmOrder.getProjectid());
        JSONObject jsonObject = projectRepository.getData(crmOrder.getProjectid());
        project1.setAmount(jsonObject.getFloat("orderamount"));
        project1.setIncome(jsonObject.getFloat("profitamount"));
        projectRepository.save(project1);
        crmOrderRepository.deleteById(id);
    }


    @Override
    public void download(List<CrmOrderDTO> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (CrmOrderDTO crmOrder : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("创建时间", crmOrder.getCreated());
            map.put("创建者ID", crmOrder.getUserid());
            map.put("项目编号", crmOrder.getProjectid());
            map.put("订单金额", crmOrder.getOrderamount());
            map.put("净利润", crmOrder.getProfitamount());
            map.put("客户", crmOrder.getCustomer());
            map.put("订单信息", crmOrder.getInfo());
            map.put("图片列表", crmOrder.getImages());
            map.put("文件列表", crmOrder.getFiles());
            map.put("运单号", crmOrder.getWaybill());
            map.put("快递公司", crmOrder.getExpress());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
